package com.lsc.record.aop;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.lsc.record.aop.annotation.OperationLogDesc;
import com.lsc.record.core.entity.DmLogsOperation;
import com.lsc.record.core.mapper.DmLogsOperationMapper;

@Component
@Aspect
public class ApiLogAopAction {
	
	@Resource
	private DmLogsOperationMapper logDao;
	
	@Pointcut("@annotation(com.lsc.record.aop.annotation.OperationLogDesc)")
	public void log() {
	}

	@Before("log()")
	public void doBefore(JoinPoint joinPoint) {
	}

	/**
	 * 只有正常返回才会执行此方法 如果程序执行失败，则不执行此方法
	 */
	@AfterReturning(returning = "returnVal", pointcut = "log()")
	public void doAfterReturning(JoinPoint joinPoint, Object returnVal) {
		
		DmLogsOperation logInfo = new DmLogsOperation();
		MethodSignature signature = (MethodSignature)joinPoint.getSignature();
		 OperationLogDesc opLog = signature.getMethod().getAnnotation(OperationLogDesc.class);
		 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
	     HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
	      
	     logInfo.setUrlPath(httpServletRequest.getRequestURI().toString());
	     logInfo.setOperationModule(opLog.module());
 
		 StringBuffer params = new StringBuffer();
		 Object[] objects = joinPoint.getArgs();
	      for (Object arg : objects) {
	         if (arg != null) {
	        	 if(params.length()>0) {
	        		 params.append(",");
	        	 }
	        	 params.append(arg.toString());
	         }
	      }
	      logInfo.setOperationDetails(params.toString());
	      logInfo.setStatusCode(1);
	      logDao.insert(logInfo, true);
	}
	
	
	  /**
     * 当接口报错时执行此方法
     */
    @AfterThrowing(pointcut = "log()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint,Throwable e) {
    	
    	StringWriter sw = new StringWriter();
    	e.printStackTrace(new PrintWriter(sw,true));
    	DmLogsOperation logInfo = new DmLogsOperation();
		MethodSignature signature = (MethodSignature)joinPoint.getSignature();
		 OperationLogDesc opLog = signature.getMethod().getAnnotation(OperationLogDesc.class);
		 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
	     HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
	      
	     logInfo.setUrlPath(httpServletRequest.getRequestURI().toString());
	     logInfo.setOperationModule(opLog.module());
 
		 StringBuffer params = new StringBuffer();
		 Object[] objects = joinPoint.getArgs();
	      for (Object arg : objects) {
	         if (arg != null) {
	        	 if(params.length()>0) {
	        		 params.append(",");
	        	 }
	        	 params.append(arg.toString());
	         }
	      }
	      logInfo.setOperationDetails(params.toString());
	      logInfo.setStatusCode(0);
	      logInfo.setSuccess(false);
	      logInfo.setErrorMessage(sw.toString());
	      logDao.insert(logInfo, true);
    }
    
    /**
     * 在接口原有的方法执行后，都会执行此处的代码（final）
     */
    @After("log()")
    public void doAfter(JoinPoint joinPoint) {
        
    }
}
